﻿using System;
using System.ServiceModel;
using System.Windows;
using System.Windows.Input;
using RemoteTestRunner.BusinessLogic;
using RemoteTestRunner.BusinessLogic.ViewModels;
using RemoteTestRunner.BusinessLogic.Views;
using RemoteTestRunner.Contracts;

namespace RemoteTestRunner.FormsUI.Wpf
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        private static void Start()
        {

            //System.Windows.Application
            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.SetCompatibleTextRenderingDefault(false);

            //Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            IoC.Container.RegisterType<IApplicationNavigationService, ApplicationNavigationService>();
            IoC.Container.RegisterType<IFileOpenDialogService, FileOpenDialogService>();
            IoC.Container.RegisterType<IFolderBrowserDialogService, FolderBrowserDialogService>();

            IoC.Container.RegisterInstance<IRtrSettings>(new RtrSettingsClient());
            var settings = IoC.Container.Resolve<IRtrSettings>();
            settings.SettingsSaved += SettingsSaved;

            //IoC.Container.RegisterType<RunnerViewModel, RunnerViewModel>();

            SetupRtrService();

            //IoC.Container.RegisterType<ProjectAdminViewModel, ProjectAdminViewModel>();

            var runnerInstance = new Runner();
            //IoC.Container.RegisterInstance<Runner>(runnerInstance);

            var mainViewModel = new RunnerViewModel();
            runnerInstance.DataContext = mainViewModel;

            SetupMenuKeyBindings(runnerInstance);

            mainViewModel.Start(
                runnerInstance,
                IoC.Container.Resolve<IApplicationNavigationService>(),
                IoC.Container.Resolve<IFileOpenDialogService>(),
                IoC.Container.Resolve<IRtrSettings>());
        }

        /// <summary>
        /// Setups the menu key bindings.
        /// </summary>
        /// <param name="runnerInstance">The runner instance.</param>
        /// <remarks>Since we're using Relay commands instead of Routed commands, this has to be handled in
        /// code instead of XAML :-)</remarks>
        private static void SetupMenuKeyBindings(FrameworkElement runnerInstance)
        {
            // Setup "Delete" shortcut
            runnerInstance.InputBindings.Add(new KeyBinding(
                                                 ((RunnerViewModel)runnerInstance.DataContext).DeleteSelectedHistoryItemsCommand,
                                                 new KeyGesture(Key.Delete)));

            // Setup "Open" shortcut
            runnerInstance.InputBindings.Add(new KeyBinding(
                                                 ((RunnerViewModel)runnerInstance.DataContext).OpenTestResultsCommand,
                                                 new KeyGesture(Key.O, ModifierKeys.Control)));
        }

        static void SettingsSaved(object sender, EventArgs e)
        {
            SetupRtrService();
        }

        private static void SetupRtrService()
        {
            var settings = IoC.Container.Resolve<IRtrSettings>();

            if (settings.UseRunnerService)
            {
                IoC.Container.RegisterInstance(GetChannel<IRtrService>("BasicHttpBinding_IRTRService", settings.RunnerServiceUrl));
            }
            else
            {
                IoC.Container.RegisterInstance<IRtrService>(new RtrLib(new RtrSettingsClient()));
            }
        }

        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            MessageBox.Show("Application exception:\n\n" + e.ExceptionObject);
        }

        internal void Application_Startup(object sender, StartupEventArgs e)
        {
            Start();
        }

        public static TChannel GetChannel<TChannel>(string endpointConfigurationName, string url)
        {
            var factory = new ChannelFactory<TChannel>(endpointConfigurationName);
            var fixedAddress = new EndpointAddress(url);

            factory.Endpoint.Address = fixedAddress;

            return factory.CreateChannel();
        }
    }
}
